package com.google.code.log4.appenders.compress;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;

import java.io.*;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipOutputStream;

public class CompressFileAppender extends FileAppender {

    protected String compressMethod;

    public CompressFileAppender(Layout layout, String filename, boolean append) throws IOException {
        super(layout, filename, append);
    }

    public CompressFileAppender() {
    }

    public CompressFileAppender(Layout layout, String filename, boolean append, boolean bufferedIO, int bufferSize) throws IOException {
        super(layout, filename, append, bufferedIO, bufferSize);
    }

    public CompressFileAppender(Layout layout, String filename) throws IOException {
        super(layout, filename);
    }

    public String getCompressMethod() {
        return compressMethod;
    }

    public void setCompressMethod(String compressMethod) {
        this.compressMethod = compressMethod;
    }

    @Override
    public void activateOptions() {
        if (compressMethod == null) {
            compressMethod = "";
        }
        super.activateOptions();    //To change body of overridden methods use File | Settings | File Templates.
    }

    @Override
    public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) throws IOException {
        LogLog.debug("setFile called: " + fileName + ", " + append);

        // It does not make sense to have immediate flush and bufferedIO.
        if (bufferedIO) {
            setImmediateFlush(false);
        }

        String extension = getFileExtension();

        String realFileName = fileName + extension;

        reset();

        File file = new File(realFileName);
        File parentDir = file.getParentFile();

        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }

        OutputStream outputStream = new FileOutputStream(file, append);

        outputStream = wrapOutputStream(outputStream);

        Writer fw = createWriter(outputStream);
        if (bufferedIO) {
            fw = new BufferedWriter(fw, bufferSize);
        }
        this.setQWForFiles(fw);
        this.fileName = fileName;
        this.fileAppend = append;
        this.bufferedIO = bufferedIO;
        this.bufferSize = bufferSize;
        writeHeader();
        LogLog.debug("setFile ended");
    }

    protected OutputStream wrapOutputStream(OutputStream outputStream) throws IOException {
        if ("zip".equalsIgnoreCase(compressMethod)) {
            outputStream = new ZipOutputStream(outputStream);
        } else if ("gz".equalsIgnoreCase(compressMethod)) {
            outputStream = new GZIPOutputStream(outputStream);
        }
        return outputStream;
    }

    protected String getFileExtension() {
        String extension;
        if ("zip".equalsIgnoreCase(compressMethod)) {
            extension = ".zip";
        } else if ("gz".equalsIgnoreCase(compressMethod)) {
            extension = ".gz";
        } else {
            extension = "";
        }
        return extension;
    }


}
